package com.auction.controller.user;

import com.auction.dto.BidDTO;
import com.auction.pojo.Auction;
import com.auction.pojo.Bid;
import com.auction.pojo.Result;
import com.auction.service.AuctionService;
import com.auction.service.BidService;
import com.auction.utils.BaseContext;
import com.auction.vo.BidWithTitle;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController("userBidController")
@RequestMapping("/user/bid")
public class BidController {

    @Autowired
    private BidService bidService;

    @Autowired
    private AuctionService auctionService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 竞价出价
     * 
     * @param bidDTO 竞价信息
     * @return 竞价结果
     */
    @PostMapping
    public Result<Boolean> bid(@RequestBody BidDTO bidDTO) {
        Long userId = BaseContext.getCurrentId();
        log.info("用户{}出价：{}", userId, bidDTO);

        // 获取拍卖品ID
        Long auctionId = bidDTO.getAuctionId();

        // 获取当前最高价格，先从Redis缓存中获取
        String auctionPriceKey = "auction:" + auctionId + ":current_price";
        BigDecimal currentPrice = (BigDecimal) redisTemplate.opsForValue().get(auctionPriceKey);

        // 如果Redis中没有价格信息，则从数据库获取并缓存
        if (currentPrice == null) {
            Auction auction = auctionService.getById(auctionId);
            if (auction != null) {
                currentPrice = auction.getStartPrice();
                Bid highestBid = bidService.getHighestBid(auctionId);
                if (highestBid != null) {
                    currentPrice = highestBid.getBidPrice();
                }

                // 将价格信息存入Redis
                redisTemplate.opsForValue().set(auctionPriceKey, currentPrice);
                // 设置过期时间为拍卖结束时间
                long ttl = java.time.Duration.between(java.time.LocalDateTime.now(), auction.getEndTime()).getSeconds();
                if (ttl > 0) {
                    redisTemplate.expire(auctionPriceKey, ttl, TimeUnit.SECONDS);
                }
            }
        }

        // 验证出价是否高于当前价格
        if (currentPrice != null && bidDTO.getBidPrice().compareTo(currentPrice) <= 0) {
            return Result.error("出价必须高于当前价格");
        }

        // 调用服务进行竞价
        boolean result = bidService.bid(bidDTO, userId);

        return Result.success(result);
    }

    /**
     * 查询拍卖品的所有竞价记录
     * 
     * @param auctionId 拍卖品ID
     * @return 竞价记录列表
     */
    @GetMapping("/auction/{auctionId}")
    public Result<List<Bid>> getByAuctionId(@PathVariable Long auctionId) {
        log.info("查询拍卖品竞价记录：auctionId={}", auctionId);

        // 尝试从Redis中获取竞价记录
        String bidListKey = "auction:" + auctionId + ":bids";
        List<Bid> bids = redisTemplate.opsForList().range(bidListKey, 0, -1);

        // 如果Redis中没有数据或数据为空，则从数据库查询
        if (bids == null || bids.isEmpty()) {
            bids = bidService.getByAuctionId(auctionId);

            // 将查询结果存入Redis
            if (bids != null && !bids.isEmpty()) {
                // 清空旧数据
                redisTemplate.delete(bidListKey);
                // 将新数据存入Redis
                for (Bid bid : bids) {
                    redisTemplate.opsForList().rightPush(bidListKey, bid);
                }

                // 设置过期时间
                Auction auction = auctionService.getById(auctionId);
                if (auction != null) {
                    long ttl = java.time.Duration.between(java.time.LocalDateTime.now(), auction.getEndTime())
                            .getSeconds();
                    if (ttl > 0) {
                        redisTemplate.expire(bidListKey, ttl, TimeUnit.SECONDS);
                    }
                }
            }
        }

        return Result.success(bids);
    }

    /**
     * 分页查询用户的竞价记录
     * 
     * @param pageNum  页码
     * @param pageSize 每页大小
     * @return 竞价记录分页结果
     */
    @GetMapping("/user")
    public Result<PageInfo<BidWithTitle>> getByUserId(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize) {
        Long userId = BaseContext.getCurrentId();
        log.info("查询用户竞价记录：userId={}, 页码={}, 每页记录数={}", userId, pageNum, pageSize);
        PageInfo<BidWithTitle> pageInfo = bidService.page(pageNum, pageSize, userId);
        return Result.success(pageInfo);
    }

    /**
     * 获取拍卖品的最高竞价记录
     * 
     * @param auctionId 拍卖品ID
     * @return 最高竞价记录
     */
    @GetMapping("/highest/{auctionId}")
    public Result<Bid> getHighestBid(@PathVariable Long auctionId) {
        log.info("查询拍卖品最高竞价：auctionId={}", auctionId);

        // 尝试从Redis中获取最高竞价
        String highestBidKey = "auction:" + auctionId + ":highest_bid";
        Bid highestBid = (Bid) redisTemplate.opsForValue().get(highestBidKey);

        // 如果Redis中没有数据，则从数据库查询
        if (highestBid == null) {
            highestBid = bidService.getHighestBid(auctionId);

            // 将查询结果存入Redis
            if (highestBid != null) {
                redisTemplate.opsForValue().set(highestBidKey, highestBid);

                // 设置过期时间
                Auction auction = auctionService.getById(auctionId);
                if (auction != null) {
                    long ttl = java.time.Duration.between(java.time.LocalDateTime.now(), auction.getEndTime())
                            .getSeconds();
                    if (ttl > 0) {
                        redisTemplate.expire(highestBidKey, ttl, TimeUnit.SECONDS);
                    }
                }
            }
        }

        return Result.success(highestBid);
    }
}